﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PowerView.Page
{
    public partial class PD_Form : Form
    {
        public PD_Form()
        {
            InitializeComponent();
        }

        double[,] Pdo = new double[16,6];// Type， MinVolt， MaxVolt， MinCurr， MaxCurr，Position

        private void PD_Form_Load(object sender, EventArgs e)
        {
            SOP_cBox.SelectedIndex = 0;
        }

        private void ShakeHand_SourceCap_Proc(byte[] cmd)
        {
            if (cmd[4] != 0) // ShakeHand Fail
            {
                switch (cmd[4])
                {
                    case 0x01:
                        MiddleWare.log_tBox.AppendText("PD Phy通信失败\r\n");
                        break;
                    case 0x02:
                        MiddleWare.log_tBox.AppendText("未检测到Source\r\n");
                        break;
                    case 0x03:
                        MiddleWare.log_tBox.AppendText("获取SourceCap超时\r\n");
                        break;
                }
            }
            else // 握手成功
            {
                int Pdo_Number = cmd[5] / 4, Pdo_Index = 0;
                Pdo_listBox.Items.Clear();
                for (int i = 0; i < Pdo_Number; i++)
                {
                    if ((cmd[6 + i * 4 + 3] & 0xD0) == 0xD0) // AVS 档位
                    {
                        Pdo[Pdo_Index, 0] = 2; // 档位类型 
                        Pdo[Pdo_Index, 1] = (Double)(cmd[6 + i * 4 + 1]) / 10; //最小电压
                        Pdo[Pdo_Index, 2] = (Double)(((cmd[6 + i * 4 + 3] & 0x02) << 7) | ((cmd[6 + i * 4 + 2] & 0xFE) >> 1)) / 10; //最大电压
                        Pdo[Pdo_Index, 3] = Pdo[Pdo_Index, 4] = (Double)(cmd[6 + i * 4 + 0]); //功率
                        Pdo_listBox.Items.Add("[ AVS ] " + Pdo[Pdo_Index, 1].ToString("0.00") + "/" + Pdo[Pdo_Index, 2].ToString("0.00") + "V," + Pdo[Pdo_Index, 4].ToString("0.00") + "W");
                    }
                    else if ((cmd[6 + i * 4 + 3] & 0xC0) == 0xC0) // PPS 档位
                    {
                        Pdo[Pdo_Index, 0] = 1; // 档位类型 0:Fixed, 1:PPS
                        Pdo[Pdo_Index, 1] = (Double)(cmd[6 + i * 4 + 1]) / 10; //最小电压
                        Pdo[Pdo_Index, 2] = (Double)(((cmd[6 + i * 4 + 3] & 0x01) << 7) | ((cmd[6 + i * 4 + 2] & 0xFE) >> 1)) / 10; //最大电压
                        Pdo[Pdo_Index, 3] = Pdo[Pdo_Index, 4] = (Double)(cmd[6 + i * 4 + 0] & 0x7F) / 20; //电流
                        Pdo_listBox.Items.Add("[ PPS ] " + Pdo[Pdo_Index, 1].ToString("0.00") + "/" + Pdo[Pdo_Index, 2].ToString("0.00") + "V," + Pdo[Pdo_Index, 4].ToString("0.00") + "A");
                    }
                    else if ((cmd[6 + i * 4 + 3] & 0xc0) == 0 && cmd[6 + i * 4 + 0] != 0) // Fixed 档位
                    {
                        Pdo[Pdo_Index, 0] = 0; // 档位类型 0:Fixed, 1:PPS
                        Pdo[Pdo_Index, 1] = Pdo[Pdo_Index, 2] = (Double)(((cmd[6 + i * 4 + 2] & 0x0F) << 6) | (cmd[6 + i * 4 + 1] & 0xFC) >> 2) / 20; //电压
                        Pdo[Pdo_Index, 3] = Pdo[Pdo_Index, 4] = (Double)(((cmd[6 + i * 4 + 1] & 0x03) << 8) | (cmd[6 + i * 4 + 0])) / 100; //电流
                        Pdo_listBox.Items.Add("[Fixed] " + Pdo[Pdo_Index, 2].ToString("0.00") + "V," + Pdo[Pdo_Index, 4].ToString("0.00") + "A");
                    }
                    else // 空挡
                        continue;

                    Pdo[Pdo_Index, 4] = i;
                    Pdo_Index++;
                }
            }
        }

        public void CMD_Proc(byte[] cmd)
        {
            switch (cmd[3])
            {
                case 0x00: // SurceCap
                    ShakeHand_SourceCap_Proc(cmd);
                    break;
                case 0x01: // Rd Comtrol
                    break;
                case 0x02: // Volt Set
                    break;
                case 0x04: //EPR SourceCap
                    ShakeHand_SourceCap_Proc(cmd);
                    break;
            }
        }

        private void Rd_Disable_Btn_Click(object sender, EventArgs e)
        {
            MiddleWare.Write_CMD(0xFF, 0x10, 0x01, new byte[] { 0x00 }, 1);
        }

        private void Rd_Enable_Btn_Click(object sender, EventArgs e)
        {
            MiddleWare.Write_CMD(0xFF, 0x10, 0x01, new byte[] { 0x03 }, 1);
        }

        private void ShakeHand_Btn_Click(object sender, EventArgs e)
        {
            MiddleWare.Write_CMD(0xFF, 0x10, 0x00, new byte[] { 20 }, 1); // Diasable Rd 200mS
            Pdo_listBox.Items.Clear();
        }

        private void DR_Swap_Btn_Click(object sender, EventArgs e)
        {
            MiddleWare.Write_CMD(0xFF, 0x10, 0x03, null, 0);
        }

        private void EPR_Btn_Click(object sender, EventArgs e)
        {
            MiddleWare.Write_CMD(0xFF, 0x10, 0x04, null, 0);
        }

        private void Pdo_listBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            Volt_textBox.Text = Pdo[Pdo_listBox.SelectedIndex, 2].ToString();
            Curr_textBox.Text = Pdo[Pdo_listBox.SelectedIndex, 3].ToString();
            if (Pdo[Pdo_listBox.SelectedIndex, 0] > 0) //PPS or AVS
            {
                Volt_textBox.Enabled = true;
            }
            else
            {
                Volt_textBox.Enabled = false;
            }
        }

        private void Set_Btn_Click(object sender, EventArgs e)
        {
            byte[] send_data = new byte[5] { 0, 0, 0, 0, 0 };
            UInt32 volt = 0;
            UInt32 curr = 0;

            send_data[0] = (byte)(Pdo[Pdo_listBox.SelectedIndex, 4] + 1);

            if (Pdo[Pdo_listBox.SelectedIndex, 0] > 0) // PPS
            {
                volt = (UInt32)(double.Parse(Volt_textBox.Text) * 1000);
                curr = (UInt32)(double.Parse(Curr_textBox.Text) * 1000);

                send_data[1] = (byte)(volt >> 8);
                send_data[2] = (byte)(volt & 0xFF);
                send_data[3] = (byte)(curr >> 8);
                send_data[4] = (byte)(curr & 0xFF);
            }
            else // Fixed
            {
                curr = (UInt32)(double.Parse(Curr_textBox.Text) * 1000);
                send_data[3] = (byte)(curr >> 8);
                send_data[4] = (byte)(curr & 0xFF);
            }

            MiddleWare.Write_CMD(0xFF, 0x10, 0x02, send_data, 5);
        }

        private void Pdo_listBox_DoubleClick(object sender, EventArgs e)
        {
            MiddleWare.Write_CMD(0xFF, 0x10, 0x02, new byte[] { (byte)(Pdo[Pdo_listBox.SelectedIndex, 4] + 1)}, 1);
        }

        private void Send_Custom_Data_Btn_Click(object sender, EventArgs e)
        {
            byte[] send_data = new byte[128];

            switch (SOP_cBox.Text)
            {
                case "SOP":
                    send_data[0] = 0x12; send_data[1] = 0x12; send_data[2] = 0x12; send_data[3] = 0x13;
                    break;
                case "SOP'":
                    send_data[0] = 0x12; send_data[1] = 0x12; send_data[2] = 0x1B; send_data[3] = 0x1B;
                    break;
                case "SOP''":
                    send_data[0] = 0x12; send_data[1] = 0x1B; send_data[2] = 0x12; send_data[3] = 0x1B;
                    break;
                case "SOP'DB":
                    send_data[0] = 0x12; send_data[1] = 0x16; send_data[2] = 0x16; send_data[3] = 0x1B;
                    break;
                case "SOP''DB":
                    send_data[0] = 0x12; send_data[1] = 0x16; send_data[2] = 0x1B; send_data[3] = 0x13;
                    break;
            }

            byte[] header = MiddleWare.HexStringToByteArray(Header_tBox.Text);

            if (header.Length != 2)
            {
                MiddleWare.log_tBox.AppendText("Header 长度必须是两个字节!!\r\n");
                Header_tBox.BackColor = Color.Pink;
                return;
            }
            Header_tBox.BackColor = Color.White;
            byte[] data = MiddleWare.HexStringToByteArray(Data_tBox.Text);

            if (data.Length % 4 != 0)
            {
                MiddleWare.log_tBox.AppendText("数据长度必须是4的整数倍!!\r\n");
                Data_tBox.BackColor = Color.Pink;
                return;
            }
            Data_tBox.BackColor = Color.White;

            send_data[4] =  (byte)(header.Length + data.Length);
            send_data[4]|= 0x80;

            send_data[5] = header[1];
            send_data[6] = header[0];

            for (int i = 0; i < data.Length; i+= 4)
            {
                send_data[7 + i] = data[i + 3];
                send_data[8 + i] = data[i + 2];
                send_data[9 + i] = data[i + 1];
                send_data[10+ i] = data[i + 0];
            }
            send_data[7 + data.Length] = 0xFF;
            send_data[8 + data.Length] = 0x14;
            send_data[9 + data.Length] = 0xA1;
            MiddleWare.Write_CMD(0xFF, 0x10, 0x0FE, send_data, (byte)(10 + data.Length));
        }

        private void Volt_textBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                Set_Btn_Click(null, null);
            }
        }
    }
}
